package com.ikingtech.platform.service.system.user.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ikingtech.framework.sdk.authenticate.operation.IdentityOps;
import com.ikingtech.framework.sdk.base.model.BatchParam;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.cache.constants.CacheConstants;
import com.ikingtech.framework.sdk.context.event.SystemInitEvent;
import com.ikingtech.framework.sdk.context.event.TenantDeleteEvent;
import com.ikingtech.framework.sdk.context.event.TenantInitEvent;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.enums.authenticate.SignEndpointTypeEnum;
import com.ikingtech.framework.sdk.enums.domain.DomainEnum;
import com.ikingtech.framework.sdk.enums.system.tenant.TenantStatusEnum;
import com.ikingtech.framework.sdk.enums.system.user.UserCategoryEnum;
import com.ikingtech.framework.sdk.enums.system.user.UserConfigTypeEnum;
import com.ikingtech.framework.sdk.enums.system.user.UserLockTypeEnum;
import com.ikingtech.framework.sdk.enums.system.user.UserSocialTypeEnum;
import com.ikingtech.framework.sdk.enums.system.variable.VariableEnum;
import com.ikingtech.framework.sdk.log.embedded.annotation.OperationLog;
import com.ikingtech.framework.sdk.user.api.UserApi;
import com.ikingtech.framework.sdk.user.api.UserMenuApi;
import com.ikingtech.framework.sdk.user.api.UserRoleApi;
import com.ikingtech.framework.sdk.user.api.UserTenantApi;
import com.ikingtech.framework.sdk.user.extension.model.UserInfoEvent;
import com.ikingtech.framework.sdk.user.model.*;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.service.system.user.entity.*;
import com.ikingtech.platform.service.system.user.exception.UserExceptionInfo;
import com.ikingtech.platform.service.system.user.service.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.time.LocalDateTime;
import java.util.*;

import static com.ikingtech.framework.sdk.context.constant.SecurityConstants.DEFAULT_PASSWORD_MODIFY_TIME;
import static com.ikingtech.framework.sdk.context.security.Identity.ADMIN_USER_ID;
import static com.ikingtech.framework.sdk.context.security.Identity.ADMIN_USER_NAME;

/**
 * 用户管理模块
 *
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
@ApiController(value = "/system/user", name = "系统管理-用户管理", description = "系统管理-用户管理")
public class UserController implements UserApi {

    private final UserRepository repo;

    private final UserConfigRepository userConfigRepo;

    private final UserCategoryRepository userCategoryRepo;

    private final UserDeptRepository userDeptRepo;

    private final UserRoleRepository userRoleRepo;

    private final UserPostRepository userPostRepo;

    private final UserSocialRepository userSocialRepo;

    private final UserTenantRepository userTenantRepo;

    private final StringRedisTemplate redisTemplate;

    private final UserRoleApi userRoleApi;

    private final UserMenuApi userMenuApi;

    private final UserTenantApi userTenantApi;

    private final ModelConverter converter;

    private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    private final IdentityOps identityOps;

    private final ApplicationContext applicationContext;

    /**
     * 添加用户
     *
     * @param user 用户信息
     * @return 返回添加的用户id
     */
    @Override
    @OperationLog(value = "添加用户", dataId = "#_res.getData()")
    @Transactional(rollbackFor = Exception.class)
    public R<String> add(UserDTO user) {
        // 检查用户名是否已存在
        if (this.repo.exists(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getUsername, user.getUsername()))) {
            throw new FrameworkException(UserExceptionInfo.DUPLICATE_USERNAME);
        }
        // 检查手机号是否已存在
        if (this.repo.exists(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getPhone, user.getPhone()))) {
            throw new FrameworkException(UserExceptionInfo.DUPLICATE_PHONE);
        }
        // 检查用户名是否包含空格
        if (null != user.getName() && user.getName().contains(Tools.Str.BLANK)) {
            throw new FrameworkException(UserExceptionInfo.USER_NAME_SHOULD_NOT_CONTAIN_BLANK);
        }
        // 检查昵称是否包含空格
        if (null != user.getNickname() && user.getNickname().contains(Tools.Str.BLANK)) {
            throw new FrameworkException(UserExceptionInfo.USER_NICKNAME_SHOULD_NOT_CONTAIN_BLANK);
        }

        // 创建用户实体
        UserDO entity = Tools.Bean.copy(user, UserDO.class);
        entity.setId(Tools.Id.uuid());
        if (Tools.Str.isBlank(entity.getId())) {
            entity.setId(Tools.Id.uuid());
        }
        if (Tools.Str.isBlank(entity.getNickname())) {
            entity.setNickname(user.getName());
        }
        if (null == user.getPlatformUser()) {
            entity.setPlatformUser(true);
        }
        entity.setPassword(this.defaultEncodedPassword());
        entity.setPasswordModifyTime(DEFAULT_PASSWORD_MODIFY_TIME);
        this.repo.save(entity);
        this.insertUserDept(entity.getId(), user.getDeptIds());
        this.insertUserPost(entity.getId(), user.getPostIds());
        this.insertUserRole(entity.getId(), user.getRoleIds());
        this.insertUserTenant(entity.getId());
        this.insertUserCategory(entity.getId(), user.getCategoryCodes());
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                // 发布用户信息事件
                UserInfoEvent event = Tools.Bean.copy(user, UserInfoEvent.class);
                event.setId(entity.getId());
                event.setType(UserInfoEvent.UserInfoEventTypeEnum.ADD);
                applicationContext.publishEvent(event);
            }
        });
        return R.ok(entity.getId());
    }

    /**
     * 加密默认密码
     *
     * @return 默认密码
     */
    private String defaultEncodedPassword() {
        // 获取系统变量中的默认密码并加密
        return this.passwordEncoder.encode(VariableEnum.resolveUserDefaultPassword(this.redisTemplate.opsForHash().get(CacheConstants.systemVariableFormat(Me.tenantCode()), VariableEnum.USER_DEFAULT_PASSWORD.name())));
    }

    /**
     * 删除用户
     *
     * @param id 用户id
     * @return 删除结果
     */
    @Override
    @OperationLog(value = "删除用户")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> delete(String id) {
        // 根据用户id获取用户实体
        UserDO entity = this.repo.getById(id);
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 删除用户与部门、角色、职位、租户、配置的关联关系
        this.userDeptRepo.remove(Wrappers.<UserDeptDO>lambdaQuery().eq(UserDeptDO::getUserId, id).eq(Tools.Str.isNotBlank(Me.tenantCode()), UserDeptDO::getTenantCode, Me.tenantCode()));
        this.userRoleRepo.remove(Wrappers.<UserRoleDO>query().lambda().eq(UserRoleDO::getUserId, id).eq(Tools.Str.isNotBlank(Me.tenantCode()), UserRoleDO::getTenantCode, Me.tenantCode()));
        this.userPostRepo.remove(Wrappers.<UserPostDO>query().lambda().eq(UserPostDO::getUserId, id).eq(Tools.Str.isNotBlank(Me.tenantCode()), UserPostDO::getTenantCode, Me.tenantCode()));
        this.userTenantRepo.remove(Wrappers.<UserTenantDO>lambdaQuery().eq(UserTenantDO::getUserId, id).eq(Tools.Str.isNotBlank(Me.tenantCode()), UserTenantDO::getTenantCode, Me.tenantCode()));
        this.userConfigRepo.remove(Wrappers.<UserConfigDO>lambdaQuery().eq(UserConfigDO::getUserId, id).eq(UserConfigDO::getTenantCode, Me.tenantCode()));
        this.userSocialRepo.remove(Wrappers.<UserSocialDO>lambdaQuery().eq(UserSocialDO::getUserId, id));
        if (DomainEnum.PLATFORM.name().equals(Me.domainCode())) {
            // 删除用户实体
            this.repo.removeById(id);
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    // 复制用户实体为事件对象
                    UserInfoEvent event = Tools.Bean.copy(entity, UserInfoEvent.class);
                    event.setType(UserInfoEvent.UserInfoEventTypeEnum.DELETE);
                    // 发布事件
                    applicationContext.publishEvent(event);
                }
            });
        }
        return R.ok();
    }

    /**
     * 更新用户
     *
     * @param user 用户信息
     * @return 返回操作结果
     */
    @Override
    @OperationLog(value = "更新用户")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> update(UserDTO user) {
        // 更新用户信息
        this.updateUser(user);
        // 更新用户部门信息
        this.updateUserDept(user.getId(), user.getDeptIds());
        // 更新用户职位信息
        this.updateUserPost(user.getId(), user.getPostIds());
        // 更新用户角色信息
        this.updateUserRole(user.getId(), user.getRoleIds());
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                // 发布事件
                UserInfoEvent event = Tools.Bean.copy(user, UserInfoEvent.class);
                event.setType(UserInfoEvent.UserInfoEventTypeEnum.UPDATE);
                applicationContext.publishEvent(event);
            }
        });
        return R.ok();
    }

    /**
     * 更新用户基本信息
     *
     * @param user 用户基本信息
     * @return 更新结果
     */
    @Override
    @OperationLog(value = "更新用户基本信息")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> updateUserInfo(UserBasicDTO user) {
        // 更新用户信息
        this.updateUser(user);
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                // 发布事件
                UserInfoEvent event = Tools.Bean.copy(user, UserInfoEvent.class);
                event.setType(UserInfoEvent.UserInfoEventTypeEnum.UPDATE);
                applicationContext.publishEvent(event);
            }
        });

        return R.ok();
    }

    /**
     * 获取所有用户基本信息
     *
     * @return 返回所有用户基本信息的DTO对象列表
     */
    @Override
    public R<List<UserBasicDTO>> allInfo() {
        return R.ok(this.converter.modelInfoConvert(this.repo.list(Wrappers.<UserDO>lambdaQuery().ne(UserDO::getAdminUser, true))));
    }

    /**
     * 分页查询用户列表
     *
     * @param queryParam 查询参数
     * @return 用户列表
     */
    @Override
    public R<List<UserDTO>> page(UserQueryParamDTO queryParam) {
        List<String> dataScope = Me.dataScope(queryParam.getDeptId());
        if (Me.invalidDataScope(dataScope)) {
            return R.ok(Collections.emptyList());
        }
        List<String> userIds = this.userDeptRepo.listObjs(Wrappers.<UserDeptDO>lambdaQuery()
                .select(UserDeptDO::getUserId)
                .in(Tools.Coll.isNotBlank(dataScope), UserDeptDO::getDeptId, dataScope)
                .in(Tools.Str.isNotBlank(Me.tenantCode()), UserDeptDO::getTenantCode, Me.tenantCode()));
        if (!Me.isAdmin() && Tools.Coll.isBlank(userIds)) {
            return R.ok(Collections.emptyList());
        }

        // 根据角色id查询用户列表
        if (Tools.Str.isNotBlank(queryParam.getRoleId())) {
            userIds = Tools.Coll.intersection(this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery()
                            .select(UserRoleDO::getUserId)
                            .eq(UserRoleDO::getRoleId, queryParam.getRoleId())
                            .eq(UserRoleDO::getTenantCode, Me.tenantCode())),
                    userIds, true);
            if (Tools.Coll.isBlank(userIds)) {
                return R.ok(Collections.emptyList());
            }
        }

        // 根据职位id查询用户列表
        if (Tools.Str.isNotBlank(queryParam.getPostId())) {
            userIds = Tools.Coll.intersection(this.userPostRepo.listObjs(Wrappers.<UserPostDO>lambdaQuery()
                            .select(UserPostDO::getUserId)
                            .eq(UserPostDO::getPostId, queryParam.getPostId())
                            .eq(UserPostDO::getTenantCode, Me.tenantCode())),
                    userIds, true);
            if (Tools.Coll.isBlank(userIds)) {
                return R.ok(Collections.emptyList());
            }
        }

        // 根据租户代码查询用户列表
        if (Tools.Str.isNotBlank(Me.tenantCode())) {
            userIds = Tools.Coll.intersection(this.userTenantRepo.listObjs(Wrappers.<UserTenantDO>lambdaQuery()
                            .select(UserTenantDO::getUserId)
                            .eq(UserTenantDO::getTenantCode, Me.tenantCode())),
                    userIds, true);
            if (Tools.Coll.isBlank(userIds)) {
                return R.ok(Collections.emptyList());
            }
        }

        // 根据查询参数查询用户列表
        queryParam.setAdmin(false);
        return R.ok(PageResult.build(this.repo.page(new Page<>(queryParam.getPage(), queryParam.getRows()), UserRepository.createWrapper(queryParam, userIds))).convertBatch(this.converter::modelBatchConvert));
    }

    /**
     * 获取用户详情
     *
     * @param id 用户id
     * @return 用户详情
     */
    @Override
    public R<UserDTO> detail(String id) {
        // 通过id获取用户实体
        UserDO entity = this.repo.getById(id);
        // 如果用户实体为空，则抛出用户未找到异常
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 将用户实体转换为用户DTO并返回
        return R.ok(this.converter.modelConvert(entity));
    }

    /**
     * 绑定用户第三方平台信息
     *
     * @param userBind 用户第三方平台绑定信息
     * @return 绑定结果
     */
    @Override
    @OperationLog(value = "绑定用户第三方平台信息")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> bindSocial(UserSocialBindDTO userBind) {
        // 验证社交信息
        for (UserSocialDTO social : userBind.getSocials()) {
            if (Tools.Str.isBlank(social.getSocialNo())) {
                throw new FrameworkException(UserExceptionInfo.INVALID_SOCIAL_NO);
            }
        }

        // 查询用户信息
        UserDO entity = this.repo.getOne(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getUsername, userBind.getUsername()));
        if (null == entity) {
            // 如果用户不存在且需要添加新用户
            if (Boolean.TRUE.equals(userBind.getAddWhenNotFound())) {
                entity = this.createUser(Tools.Id.uuid(),
                        Tools.Str.isNotBlank(userBind.getUsername()) ? userBind.getUsername() : userBind.getPhone(),
                        Tools.Str.isNotBlank(userBind.getName()) ? userBind.getName() : userBind.getUsername(),
                        this.defaultEncodedPassword(),
                        false);
                this.repo.save(entity);
                this.userCategoryRepo.save(this.createUserCategory(entity.getId(), UserCategoryEnum.NORMAL_USER));
            } else {
                // 如果用户不存在且不需要添加新用户
                throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
            }
        } else {
            // 如果用户存在且需要验证密码
            if (Boolean.TRUE.equals(userBind.getValidatePassword()) &&
                    !passwordEncoder.matches(userBind.getPassword(), entity.getPassword())) {
                throw new FrameworkException(UserExceptionInfo.INVALID_USERNAME_OR_PASSWORD);
            }
            // 下线微信小程序登录
            this.identityOps.offline(entity.getId(), SignEndpointTypeEnum.WECHAT_MINI);
        }

        // 获取用户id
        String userId = entity.getId();

        // 查询已存在的第三方平台信息
        List<UserSocialDO> userSocialEntities = this.userSocialRepo.list(Wrappers.<UserSocialDO>lambdaQuery()
                .eq(UserSocialDO::getUserId, userId)
                .in(UserSocialDO::getSocialType, Tools.Coll.convertList(userBind.getSocials(), UserSocialDTO::getSocialType))
                .in(UserSocialDO::getSocialId, Tools.Coll.convertList(userBind.getSocials(), UserSocialDTO::getSocialId)));

        // 如果存在已存在的第三方平台信息，则下线并删除
        if (Tools.Coll.isNotBlank(userSocialEntities)) {
            userSocialEntities.forEach(userSocialEntity -> this.identityOps.offline(userSocialEntity.getUserId(), UserSocialTypeEnum.valueOf(userSocialEntity.getSocialType()).signEndpointType));
            this.userSocialRepo.removeBatchByIds(Tools.Coll.convertList(userSocialEntities, UserSocialDO::getId));
        }

        // 保存新的第三方平台信息
        this.userSocialRepo.saveBatch(Tools.Coll.convertList(userBind.getSocials(), social -> {
            UserSocialDO socialEntity = Tools.Bean.copy(social, UserSocialDO.class);
            socialEntity.setId(Tools.Id.uuid());
            socialEntity.setUserId(userId);
            return socialEntity;
        }));

        return R.ok();
    }

    /**
     * 根据用户编号重置密码
     *
     * @param id 用户编号
     * @return 重置密码结果
     */
    @Override
    @OperationLog(value = "根据用户编号重置密码")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> resetPassword(String id) {
        // 根据用户编号获取用户实体
        UserDO entity = this.repo.getById(id);
        if (null == entity) {
            // 如果用户实体为空，则抛出用户未找到异常
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 重置密码并设置密码修改时间为当前时间
        entity.setPassword(this.defaultEncodedPassword());
        entity.setPasswordModifyTime(LocalDateTime.now());
        // 更新用户实体
        this.repo.updateById(entity);
        return R.ok();
    }

    /**
     * 重置租户管理员密码
     *
     * @param tenantCode 租户代码
     * @return 返回操作结果
     */
    @Override
    @OperationLog(value = "重置租户管理员密码")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> resetTenantAdminUserPassword(String tenantCode) {
        // 根据租户代码查询管理员用户
        UserDO entity = this.repo.getOne(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getUsername, Tools.Str.format("{}_admin", tenantCode)));
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 生成默认编码后的密码
        String password = this.defaultEncodedPassword();
        // 设置密码和密码修改时间
        entity.setPassword(password);
        entity.setPasswordModifyTime(LocalDateTime.now());
        // 更新管理员用户信息
        this.repo.updateById(entity);
        return R.ok();
    }

    /**
     * 修改密码
     *
     * @param modifyParam 修改参数
     * @return 修改结果
     */
    @Override
    @OperationLog(value = "修改密码")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> modifyPassword(UserPasswordModifyParamDTO modifyParam) {
        // 根据用户id获取用户实体
        UserDO entity = this.repo.getById(modifyParam.getUserId());
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 验证旧密码是否正确
        if (!this.passwordEncoder.matches(modifyParam.getOldPassword(), entity.getPassword())) {
            throw new FrameworkException(UserExceptionInfo.INVALID_OLD_PASSWORD);
        }
        // 验证新密码是否与旧密码相同
        if (Tools.Str.equals(modifyParam.getOldPassword(), modifyParam.getNewPassword())) {
            throw new FrameworkException(UserExceptionInfo.PASSWORD_SAME_WITH_OLD_ONE);
        }
        // 更新密码和密码修改时间
        entity.setPassword(this.passwordEncoder.encode(modifyParam.getNewPassword()));
        entity.setPasswordModifyTime(LocalDateTime.now());
        this.repo.updateById(entity);
        return R.ok();
    }

    /**
     * 锁定用户
     *
     * @param username 用户名
     * @return 锁定结果
     */
    @Override
    @OperationLog(value = "锁定用户")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> lock(String username) {
        // 根据用户名查询用户实体
        UserDO entity = this.repo.getOne(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getUsername, username));
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 如果用户已锁定，则直接返回成功
        if (Boolean.TRUE.equals(entity.getLocked())) {
            return R.ok();
        }
        // 设置用户锁定状态为true，并设置锁定类型为LOCK
        entity.setLocked(true);
        entity.setLockType(UserLockTypeEnum.LOCK.name());
        // 更新用户实体
        this.repo.updateById(entity);
        // 将用户下线
        this.identityOps.offline(entity.getId());
        return R.ok();
    }

    /**
     * 解锁用户
     *
     * @param username 用户名
     * @return 解锁结果
     */
    @Override
    @OperationLog(value = "解锁用户")
    @Transactional(rollbackFor = Exception.class)
    public R<Object> unlock(String username) {
        // 根据用户名查询用户实体
        UserDO entity = this.repo.getOne(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getUsername, username));
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 如果用户未被锁定，则直接返回成功
        if (Boolean.FALSE.equals(entity.getLocked())) {
            return R.ok();
        }
        // 更新用户状态为未锁定
        entity.setLocked(false);
        entity.setLockType(UserLockTypeEnum.NO_LOCK.name());
        this.repo.updateById(entity);
        return R.ok();
    }

    /**
     * 根据角色id批量查询用户基本信息
     *
     * @param roleIds 角色id列表
     * @return 用户基本信息列表
     */
    @Override
    public R<List<UserBasicDTO>> listInfoByRoleIds(BatchParam<String> roleIds) {
        // 如果角色id列表为空，则返回空列表
        if (Tools.Coll.isBlank(roleIds.getList())) {
            return R.ok(Collections.emptyList());
        }
        // 查询用户id列表
        List<String> userIds = this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery()
                .select(UserRoleDO::getUserId)
                .in(UserRoleDO::getRoleId, roleIds.getList()));
        // 如果用户id列表为空，则返回空列表
        if (Tools.Coll.isBlank(userIds)) {
            return R.ok(Collections.emptyList());
        }
        // 根据用户id列表查询用户基本信息列表，并进行转换
        return R.ok(this.converter.modelInfoConvert(this.repo.listByIds(userIds)));
    }

    /**
     * 根据角色id列表查询用户列表
     *
     * @param roleIds 角色id列表
     * @return 用户列表
     */
    @Override
    public R<List<UserDTO>> listByRoleIds(BatchParam<String> roleIds) {
        List<String> userIds = this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery()
                .select(UserRoleDO::getUserId)
                .in(UserRoleDO::getRoleId, roleIds));
        if (Tools.Coll.isBlank(userIds)) {
            return R.ok(Collections.emptyList());
        }
        return R.ok(this.converter.modelBatchConvert(this.repo.listByIds(userIds)));
    }

    /**
     * 根据角色id获取用户id列表
     *
     * @param roleId 角色id
     * @return 用户id列表
     */
    @Override
    public R<List<String>> listIdByRoleId(String roleId) {
        return R.ok(this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery()
                .select(UserRoleDO::getUserId)
                .eq(UserRoleDO::getRoleId, roleId)
                .eq(UserRoleDO::getTenantCode, Me.tenantCode())));
    }


    /**
     * 根据部门id获取用户id列表
     *
     * @param deptId 部门id
     * @return 用户id列表
     */
    @Override
    public R<List<String>> listIdByDeptId(String deptId) {
        return R.ok(this.userDeptRepo.listObjs(Wrappers.<UserDeptDO>lambdaQuery()
                .select(UserDeptDO::getUserId)
                .eq(UserDeptDO::getDeptId, deptId)));
    }

    /**
     * 根据岗位id批量获取用户基本信息
     *
     * @param postIds 岗位id列表
     * @return 用户基本信息列表
     */
    @Override
    public R<List<UserBasicDTO>> listInfoByPostIds(BatchParam<String> postIds) {
        // 如果岗位id列表为空，则返回空列表
        if (Tools.Coll.isBlank(postIds.getList())) {
            return R.ok(Collections.emptyList());
        }
        // 获取岗位id对应的用户id列表
        List<String> userIds = this.userPostRepo.listObjs(Wrappers.<UserPostDO>lambdaQuery()
                .select(UserPostDO::getUserId)
                .in(UserPostDO::getPostId, postIds.getList())
                .eq(UserPostDO::getTenantCode, Me.tenantCode()));
        // 如果用户id列表为空，则返回空列表
        if (Tools.Coll.isBlank(userIds)) {
            return R.ok(Collections.emptyList());
        }
        // 根据用户id列表获取用户基本信息列表，并进行转换
        return R.ok(this.converter.modelInfoConvert(this.repo.listByIds(userIds)));
    }

    /**
     * 根据岗位id获取帖子所属用户列表
     *
     * @param postId 帖子id
     * @return 岗位所属用户列表
     */
    @Override
    public R<List<String>> listIdByPostId(String postId) {
        return R.ok(this.userPostRepo.listObjs(Wrappers.<UserPostDO>lambdaQuery()
                .select(UserPostDO::getUserId)
                .eq(UserPostDO::getPostId, postId)
                .eq(UserPostDO::getTenantCode, Me.tenantCode())));
    }

    /**
     * 根据菜单编码批量查询用户基本信息
     *
     * @param menuCodes 菜单编码列表
     * @return 用户基本信息列表
     */
    @Override
    public R<List<UserBasicDTO>> listInfoByMenuCodes(BatchParam<String> menuCodes) {
        // 根据菜单编码列表获取菜单id列表
        List<String> menuIds = this.userMenuApi.loadIdByCodes(menuCodes.getList(), Me.tenantCode());
        // 根据菜单id列表获取角色id列表
        List<String> roleIds = this.userRoleApi.loadIdByMenuIds(menuIds, Me.tenantCode());
        // 根据角色id列表查询用户基本信息列表
        return R.ok(this.loadUserByRoleIds(roleIds));
    }

    /**
     * 根据菜单编码获取用户基本信息列表
     *
     * @param menuCode 菜单编码
     * @return 用户基本信息列表
     */
    @Override
    public R<List<UserBasicDTO>> listInfoByMenuCode(String menuCode) {
        // 根据菜单编码获取菜单id
        String menuId = this.userMenuApi.loadIdByCode(menuCode, Me.tenantCode());
        // 根据菜单id获取角色id列表
        List<String> roleIds = this.userRoleApi.loadIdByMenuId(menuId, Me.tenantCode());
        // 根据角色id列表获取用户基本信息列表
        return R.ok(this.loadUserByRoleIds(roleIds));
    }

    /**
     * 根据id批量查询用户基本信息
     *
     * @param ids 批量查询的id列表
     * @return 查询结果
     */
    @Override
    public R<List<UserBasicDTO>> listInfoByIds(BatchParam<String> ids) {
        // 如果id列表为空，则返回空列表
        if (Tools.Coll.isBlank(ids.getList())) {
            return R.ok(Collections.emptyList());
        }
        // 调用repo的listByIds方法查询用户基本信息，并使用converter进行转换
        return R.ok(this.converter.modelInfoConvert(this.repo.listByIds(ids.getList())));
    }

    /**
     * 根据id批量获取用户基本信息
     *
     * @param ids 用户id列表
     * @return 用户基本信息映射结果
     */
    @Override
    public R<Map<String, UserBasicDTO>> mapInfoByIds(BatchParam<String> ids) {
        // 如果id列表为空，则返回空的映射结果
        if (Tools.Coll.isBlank(ids.getList())) {
            return R.ok(new HashMap<>());
        }
        // 将数据库查询结果转换为用户基本信息映射结果
        return R.ok(Tools.Coll.convertMap(this.converter.modelInfoConvert(this.repo.listByIds(ids.getList())), UserBasicDTO::getId));
    }

    /**
     * 根据id批量查询用户信息
     *
     * @param ids 批量查询的id列表
     * @return 查询结果
     */
    @Override
    public R<List<UserDTO>> listByIds(BatchParam<String> ids) {
        // 如果id列表为空，则返回空列表
        if (Tools.Coll.isBlank(ids.getList())) {
            return R.ok(Collections.emptyList());
        }
        // 调用repository的listByIds方法查询数据，并使用converter进行模型转换
        return R.ok(this.converter.modelBatchConvert(this.repo.listByIds(ids.getList())));
    }

    /**
     * 根据id获取用户基本信息
     *
     * @param id 用户id
     * @return 用户基本信息
     */
    @Override
    public R<UserBasicDTO> getInfoById(String id) {
        // 通过id获取用户实体
        UserDO entity = this.repo.getById(id);
        // 如果用户实体为空，则抛出用户未找到异常
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 将用户实体转换为用户基本信息并返回
        return R.ok(this.converter.modelInfoConvert(entity));
    }

    /**
     * 根据凭证获取用户信息
     *
     * @param credentialName 凭证名称
     * @return 用户基本信息DTO对象
     */
    @Override
    public R<UserBasicDTO> getInfoByCredential(String credentialName) {
        // 使用lambdaQuery方法查询用户实体
        UserDO entity = this.repo.getOne(Wrappers.<UserDO>lambdaQuery()
                .eq(UserDO::getUsername, credentialName)
                .or()
                .eq(UserDO::getPhone, credentialName)
                .or()
                .eq(UserDO::getEmail, credentialName)
                .or()
                .eq(UserDO::getIdentityNo, credentialName));
        // 如果查询结果为空，则抛出用户未找到异常
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 返回用户基本信息DTO对象
        return R.ok(this.converter.modelInfoConvert(entity));
    }

    /**
     * 根据社交账号获取用户基本信息
     *
     * @param queryParam 社交账号查询参数
     * @return 用户基本信息
     */
    @Override
    public R<UserBasicDTO> getInfoBySocial(UserSocialQueryParamDTO queryParam) {
        // 根据社交账号id和社交账号号获取用户id
        UserDO entity = this.repo.getById(this.userSocialRepo.getObj(Wrappers.<UserSocialDO>lambdaQuery()
                .select(UserSocialDO::getUserId)
                .eq(UserSocialDO::getSocialId, queryParam.getSocialId())
                .eq(UserSocialDO::getSocialNo, queryParam.getSocialNo()), String.class::cast));
        // 如果用户不存在，则抛出异常
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 将用户实体转换为用户基本信息DTO，并返回
        return R.ok(this.converter.modelInfoConvert(entity));
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 当前登录用户信息
     */
    @Override
    public R<UserBasicDTO> getLoginUser() {
        // 通过id获取用户实体
        UserDO entity = this.repo.getById(Me.id());
        // 如果用户实体为空，则抛出用户未找到异常
        if (null == entity) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 将用户实体转换为用户基本信息DTO，并返回成功结果
        return R.ok(this.converter.modelInfoConvert(entity));
    }

    /**
     * 更新用户配置
     *
     * @param userConfig 用户配置信息
     * @return 返回操作结果
     */
    @Override
    @OperationLog(value = "更新用户配置")
    public R<Object> updateConfig(UserConfigDTO userConfig) {
        List<UserConfigInfoDTO> configs = userConfig.getConfigInfoList();
        String userId = Boolean.TRUE.equals(userConfig.getGlobal()) ? "global" : userConfig.getUserId();
        List<UserConfigDO> entities = this.userConfigRepo.list(Wrappers.<UserConfigDO>lambdaQuery()
                .eq(UserConfigDO::getUserId, userId)
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserConfigDO::getTenantCode, Me.tenantCode()));
        Map<String, UserConfigDO> configMap = Tools.Coll.convertMap(entities, UserConfigDO::getType, entity -> entity);
        List<UserConfigDO> newEntities = Tools.Coll.convertList(configs, config -> {
            UserConfigDO newEntity = configMap.computeIfAbsent(config.getType().name(), t -> {
                UserConfigDO entity = new UserConfigDO();
                entity.setId(Tools.Id.uuid());
                return entity;
            });
            newEntity.setType(config.getType().name());
            newEntity.setUserId(userId);
            newEntity.setValue(config.getValue());
            newEntity.setGlobal(userConfig.getGlobal());
            newEntity.setTenantCode(Me.tenantCode());
            return newEntity;
        });
        if (Tools.Coll.isNotBlank(newEntities)) {
            this.userConfigRepo.saveOrUpdateBatch(newEntities);
            this.redisTemplate.opsForHash().putAll(CacheConstants.userConfigFormat(userConfig.getUserId(), Me.tenantCode()), Tools.Coll.convertMap(newEntities, UserConfigDO::getType, UserConfigDO::getValue));
        }
        return R.ok();
    }

    /**
     * 根据登录用户获取配置信息
     *
     * @param global 是否为全局配置
     * @return 配置信息
     */
    @Override
    public R<UserConfigDTO> listConfigByLoginUser(Boolean global) {
        String userId = Boolean.TRUE.equals(global) ? "global" : Me.id();
        List<UserConfigDO> entities = this.userConfigRepo.list(Wrappers.<UserConfigDO>lambdaQuery()
                .eq(UserConfigDO::getUserId, userId)
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserConfigDO::getTenantCode, Me.tenantCode()));
        if (Tools.Coll.isBlank(entities)) {
            return R.ok();
        }
        UserConfigDTO result = new UserConfigDTO();
        result.setUserId(userId);
        result.setGlobal(Boolean.TRUE.equals(global));
        result.setConfigInfoList(Tools.Coll.convertList(entities, entity -> Tools.Bean.copy(entity, UserConfigInfoDTO.class)));
        return R.ok(result);
    }

    /**
     * 获取前端灰度值
     *
     * @return 响应结果
     */
    @Override
    public R<String> getFrontGrayScale() {
        return R.ok(this.userConfigRepo.getObj(Wrappers.<UserConfigDO>lambdaQuery()
                .select(UserConfigDO::getValue)
                .eq(UserConfigDO::getUserId, "global")
                .eq(UserConfigDO::getType, UserConfigTypeEnum.FRONT_GRAY_SCALE.name()), String.class::cast));
    }

    /**
     * 获取用户最近一次登录的租户
     *
     * @return 用户最近一次登录的租户信息
     */
    @Override
    @OperationLog(value = "获取用户最近一次登录租户")
    public R<Object> getRecentTenantByLoginUser() {
        // 获取用户最近一次登录的租户代码
        String tenantCode = this.userTenantRepo.getObj(Wrappers.<UserTenantDO>lambdaQuery()
                .select(UserTenantDO::getTenantCode)
                .eq(UserTenantDO::getRecentLogin, true), String.class::cast);
        // 加载租户信息
        UserTenantDTO tenant = this.userTenantApi.loadByCode(tenantCode);
        // 如果租户为空或者租户状态为正常，则返回空
        if (null == tenant || TenantStatusEnum.NORMAL.equals(tenant.getTenantStatus())) {
            return R.ok();
        }
        // 返回租户信息
        return R.ok(tenant);
    }

    /**
     * 记录用户登录租户
     *
     * @param tenantCode 租户代码
     * @return 登录结果
     */
    @Override
    @OperationLog(value = "记录用户登录租户")
    public R<Object> rememberUserLoginTenant(String tenantCode) {
        // 获取用户与租户的关联信息
        List<UserTenantDO> userTenantEntities = this.userTenantRepo.list(Wrappers.<UserTenantDO>lambdaQuery()
                .eq(UserTenantDO::getUserId, Me.id()));
        if (Tools.Coll.isBlank(userTenantEntities)) {
            return R.ok();
        }
        // 更新用户与租户的关联信息
        this.userTenantRepo.updateBatchById(Tools.Coll.traverse(userTenantEntities, entity -> {
            entity.setRecentLogin(Tools.Str.equals(tenantCode, entity.getTenantCode()));
            return entity;
        }));
        return R.ok();
    }

    /**
     * 根据当前登录用户获取用户类别列表
     *
     * @return 返回用户类别列表
     */
    @Override
    public R<List<UserCategoryDTO>> listCategoryByLoginUser() {
        return R.ok(Tools.Array.convertList(UserCategoryEnum.values(), value -> {
            switch (value) {
                case PLATFORM_ADMINISTRATOR -> {
                    return Me.categoryCodes().contains(UserCategoryEnum.PLATFORM_ADMINISTRATOR.name()) ||
                            Me.categoryCodes().contains(UserCategoryEnum.TENANT_ADMINISTRATOR.name()) ||
                            Me.categoryCodes().contains(UserCategoryEnum.NORMAL_USER.name());
                }
                case TENANT_ADMINISTRATOR -> {
                    return Me.categoryCodes().contains(UserCategoryEnum.TENANT_ADMINISTRATOR.name());
                }
                default -> {
                    return false;
                }
            }
        }, value -> {
            UserCategoryDTO category = new UserCategoryDTO();
            category.setCategory(value);
            category.setCategoryName(value.description);
            return category;
        }));
    }

    /**
     * 根据姓名获取用户列表
     *
     * @param name 姓名
     * @return 返回用户列表
     */
    @Override
    public R<List<String>> listIdByName(String name) {
        return R.ok(this.repo.listObjs(Wrappers.<UserDO>lambdaQuery().like(UserDO::getName, name)));
    }

    /**
     * 插入用户部门关联信息
     *
     * @param userId  用户id
     * @param deptIds 部门id列表
     */
    public void insertUserDept(String userId, List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return;
        }
        // 将部门id列表转换为UserDeptDO对象列表
        this.userDeptRepo.saveBatch(Tools.Coll.convertList(deptIds, Tools.Str::isNotBlank, deptId -> {
            UserDeptDO userDeptEntity = new UserDeptDO();
            userDeptEntity.setId(Tools.Id.uuid());
            userDeptEntity.setUserId(userId);
            userDeptEntity.setDeptId(deptId);
            userDeptEntity.setTenantCode(Me.tenantCode());
            return userDeptEntity;
        }));
    }

    /**
     * 插入用户岗位关系
     *
     * @param userId  用户id
     * @param postIds 岗位id列表
     */
    private void insertUserPost(String userId, List<String> postIds) {
        // 将岗位id列表转换为UserPostDO对象列表
        this.userPostRepo.saveBatch(Tools.Coll.convertList(postIds,
                Tools.Str::isNotBlank,
                postId -> {
                    UserPostDO userPostEntity = new UserPostDO();
                    userPostEntity.setId(Tools.Id.uuid());
                    userPostEntity.setUserId(userId);
                    userPostEntity.setPostId(postId);
                    userPostEntity.setTenantCode(Me.tenantCode());
                    return userPostEntity;
                }));
    }

    /**
     * 插入用户角色关系
     *
     * @param userId  用户id
     * @param roleIds 角色id列表
     */
    private void insertUserRole(String userId, List<String> roleIds) {
        // 将角色id列表转换为用户角色实体列表
        this.userRoleRepo.saveBatch(Tools.Coll.convertList(roleIds,
                Tools.Str::isNotBlank,
                roleId -> {
                    UserRoleDO userRoleEntity = new UserRoleDO();
                    userRoleEntity.setId(Tools.Id.uuid());
                    userRoleEntity.setUserId(userId);
                    userRoleEntity.setRoleId(roleId);
                    userRoleEntity.setTenantCode(Me.tenantCode());
                    userRoleEntity.setDomainCode(Me.domainCode());
                    userRoleEntity.setAppCode(Me.appCode());
                    return userRoleEntity;
                }));
    }

    /**
     * 插入用户租户信息
     *
     * @param userId 用户id
     */
    private void insertUserTenant(String userId) {
        // 如果租户代码为空，则直接返回
        if (Tools.Str.isBlank(Me.tenantCode())) {
            return;
        }
        // 创建用户租户实体
        UserTenantDO entity = new UserTenantDO();
        entity.setId(Tools.Id.uuid());
        entity.setUserId(userId);
        entity.setTenantCode(Me.tenantCode());
        // 保存用户租户信息
        this.userTenantRepo.save(entity);
    }


    /**
     * 插入用户类别
     *
     * @param userId        用户id
     * @param categoryCodes 类别代码列表
     */
    private void insertUserCategory(String userId, List<String> categoryCodes) {
        // 保存批次
        this.userCategoryRepo.saveBatch(
                // 将空列表替换为默认的类别代码
                Tools.Coll.convertList(
                        Tools.Coll.isBlank(categoryCodes) ?
                                Tools.Coll.newList(UserCategoryEnum.NORMAL_USER.name()) :
                                categoryCodes,
                        // 创建实体对象
                        categoryCode -> {
                            UserCategoryDO entity = new UserCategoryDO();
                            entity.setId(Tools.Id.uuid());
                            entity.setUserId(userId);
                            entity.setCategoryCode(categoryCode);
                            return entity;
                        })
        );
    }

    /**
     * 更新用户部门信息
     *
     * @param userId  用户id
     * @param deptIds 部门id列表
     */
    private void updateUserDept(String userId, List<String> deptIds) {
        // 删除用户部门信息
        this.userDeptRepo.remove(Wrappers.<UserDeptDO>lambdaQuery()
                .eq(UserDeptDO::getUserId, userId)
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserDeptDO::getTenantCode, Me.tenantCode()));
        // 插入用户部门信息
        this.insertUserDept(userId, deptIds);
    }

    /**
     * 更新用户帖子信息
     *
     * @param userId  用户id
     * @param postIds 帖子id列表
     */
    private void updateUserPost(String userId, List<String> postIds) {
        // 删除用户帖子信息
        this.userPostRepo.remove(Wrappers.<UserPostDO>query().lambda()
                .eq(UserPostDO::getUserId, userId)
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserPostDO::getTenantCode, Me.tenantCode()));
        // 插入用户帖子信息
        this.insertUserPost(userId, postIds);
    }

    /**
     * 更新用户角色
     *
     * @param userId  用户id
     * @param roleIds 角色id列表
     */
    private void updateUserRole(String userId, List<String> roleIds) {
        // 删除用户的角色
        this.userRoleRepo.remove(Wrappers.<UserRoleDO>query().lambda()
                .eq(UserRoleDO::getUserId, userId)
                .eq(Tools.Str.isNotBlank(Me.tenantCode()), UserRoleDO::getTenantCode, Me.tenantCode())
                .eq(Tools.Str.isNotBlank(Me.appCode()), UserRoleDO::getAppCode, Me.appCode()));
        // 插入用户的角色
        this.insertUserRole(userId, roleIds);
    }

    /**
     * 更新用户信息
     *
     * @param user 用户基本信息DTO
     */
    private void updateUser(UserBasicDTO user) {
        // 检查用户是否存在
        if (!this.repo.exists(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getId, user.getId()))) {
            throw new FrameworkException(UserExceptionInfo.USER_NOT_FOUND);
        }
        // 检查用户名是否重复
        if (this.repo.exists(Wrappers.<UserDO>lambdaQuery().ne(UserDO::getId, user.getId()).eq(UserDO::getUsername, user.getUsername()))) {
            throw new FrameworkException(UserExceptionInfo.DUPLICATE_USERNAME);
        }
        // 检查手机号是否重复
        if (this.repo.exists(Wrappers.<UserDO>lambdaQuery().ne(UserDO::getId, user.getId()).eq(UserDO::getPhone, user.getPhone()))) {
            throw new FrameworkException(UserExceptionInfo.DUPLICATE_PHONE);
        }
        // 更新用户信息
        this.repo.updateById(Tools.Bean.copy(user, UserDO.class));
    }

    /**
     * 创建用户
     *
     * @param userId      用户id
     * @param username    用户名
     * @param name        姓名
     * @param password    密码
     * @param masterAdmin 是否为管理员
     * @return 创建的用户实体
     */
    private UserDO createUser(String userId, String username, String name, String password, Boolean masterAdmin) {
        UserDO entity = new UserDO();
        entity.setId(userId);
        entity.setUsername(username);
        entity.setName(name);
        entity.setNickname(name);
        entity.setPassword(password);
        entity.setPasswordModifyTime(DEFAULT_PASSWORD_MODIFY_TIME);
        entity.setPlatformUser(true);
        entity.setAdminUser(masterAdmin);
        return entity;
    }


    /**
     * 创建用户分类
     *
     * @param userId   用户id
     * @param category 分类枚举
     * @return 用户分类实体
     */
    private UserCategoryDO createUserCategory(String userId, UserCategoryEnum category) {
        UserCategoryDO entity = new UserCategoryDO();
        // 生成唯一id
        entity.setId(Tools.Id.uuid());
        // 设置用户id
        entity.setUserId(userId);
        // 设置分类代码
        entity.setCategoryCode(category.name());
        return entity;
    }


    /**
     * 根据角色id列表加载用户基本信息列表
     *
     * @param roleIds 角色id列表
     * @return 用户基本信息列表
     */
    private List<UserBasicDTO> loadUserByRoleIds(List<String> roleIds) {
        if (Tools.Coll.isBlank(roleIds)) {
            return new ArrayList<>();
        }
        // 获取用户id列表
        List<String> userIds = this.userRoleRepo.listObjs(Wrappers.<UserRoleDO>lambdaQuery()
                .select(UserRoleDO::getUserId)
                .in(UserRoleDO::getRoleId, roleIds));
        if (Tools.Coll.isBlank(userIds)) {
            return new ArrayList<>();
        }
        // 根据用户id列表加载用户基本信息列表
        return this.converter.modelInfoConvert(this.repo.listByIds(userIds));
    }

    /**
     * 注册系统初始化事件监听器
     */
    @EventListener(SystemInitEvent.class)
    public void systemInitEventListener() {
        // 检查平台管理员用户是否存在，如果不存在则创建
        if (!this.repo.exists(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getId, ADMIN_USER_ID))) {
            this.repo.save(this.createUser(ADMIN_USER_ID, ADMIN_USER_NAME, "平台管理员", this.defaultEncodedPassword(), true));
        }
        // 检查平台管理员用户类别是否存在，如果不存在则创建
        if (!this.userCategoryRepo.exists(Wrappers.<UserCategoryDO>lambdaQuery().eq(UserCategoryDO::getUserId, ADMIN_USER_ID))) {
            this.userCategoryRepo.save(this.createUserCategory(ADMIN_USER_ID, UserCategoryEnum.PLATFORM_ADMINISTRATOR));
        }

        // 检查前端页面灰度模式配置是否存在，如果不存在则创建
        if (!this.userConfigRepo.exists(Wrappers.<UserConfigDO>lambdaQuery().eq(UserConfigDO::getType, UserConfigTypeEnum.FRONT_GRAY_SCALE.name()))) {
            UserConfigDO entity = new UserConfigDO();
            entity.setId(Tools.Id.uuid());
            entity.setUserId("global");
            entity.setGlobal(true);
            entity.setType(UserConfigTypeEnum.FRONT_GRAY_SCALE.name());
            entity.setValue("0");
            this.userConfigRepo.save(entity);
        }
    }

    /**
     * 处理租户初始化事件的监听器方法
     *
     * @param event 租户初始化事件对象
     */
    @EventListener
    public void tenantInitEventListener(TenantInitEvent event) {
        // 生成用户id
        String userId = Tools.Str.format("{}_{}", event.getCode(), ADMIN_USER_ID);
        // 创建用户并保存到数据库
        this.repo.saveOrUpdate(this.createUser(
                userId,
                Tools.Str.format("{}_{}", event.getCode(), ADMIN_USER_NAME),
                "系统管理员",
                this.defaultEncodedPassword(),
                true
        ));
        // 创建用户分类并保存到数据库
        this.userCategoryRepo.saveOrUpdate(this.createUserCategory(userId, UserCategoryEnum.TENANT_ADMINISTRATOR));
        // 创建用户租户关联对象并保存到数据库
        UserTenantDO userTenantEntity = new UserTenantDO();
        userTenantEntity.setId(Tools.Id.uuid());
        userTenantEntity.setUserId(userId);
        userTenantEntity.setTenantCode(event.getCode());
        userTenantEntity.setRecentLogin(false);
        this.userTenantRepo.save(userTenantEntity);
    }

    /**
     * 处理租户删除事件
     *
     * @param event 租户删除事件对象
     */
    @EventListener
    public void tenantDeleteEventListener(TenantDeleteEvent event) {
        // 根据租户代码查询用户并删除
        this.repo.remove(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getUsername, Tools.Str.format("{}_{}", event.getCode(), ADMIN_USER_NAME)));
        // 根据租户代码删除用户部门关联信息
        this.userDeptRepo.remove(Wrappers.<UserDeptDO>lambdaQuery().eq(UserDeptDO::getTenantCode, event.getCode()));
        // 根据租户代码删除用户职位关联信息
        this.userPostRepo.remove(Wrappers.<UserPostDO>lambdaQuery().eq(UserPostDO::getTenantCode, event.getCode()));
        // 根据租户代码删除用户角色关联信息
        this.userRoleRepo.remove(Wrappers.<UserRoleDO>lambdaQuery().eq(UserRoleDO::getTenantCode, event.getCode()));
        // 根据租户代码删除用户租户关联信息
        this.userTenantRepo.remove(Wrappers.<UserTenantDO>lambdaQuery().eq(UserTenantDO::getTenantCode, event.getCode()));
        // 根据租户代码删除用户配置信息
        this.userConfigRepo.remove(Wrappers.<UserConfigDO>lambdaQuery().eq(UserConfigDO::getTenantCode, event.getCode()));
    }
}
